toastLog("版本：24.9.6");
let 酷狗音乐 = "酷狗音乐";
try {
  hamibot.env;
  toastLog("当前在haimbot运行~切换识别");
  运行环境haimbot = true;
} catch (error) {
  var qq = require("/sdcard/脚本/QQ");
  qq.init();
  sleep(1000);
  var 运行环境haimbot = false;
  toastLog("本地运行");
}
FloatyUtil();
FloatyUtilinit();
toastLog("加载文字识别~~");
sleep(3000);

// 设置最低亮度 同时关闭自动亮度
// device.setBrightnessMode(0);
// device.setBrightness(1);
device.setMusicVolume(0);
threads.start(function () {
  findAndClick("允许|立即开始");
});
if (!requestScreenCapture()) {
  toast("请求截图失败");
  exit();
}

酷狗任务(酷狗音乐);

function 酷狗任务(str) {
  showLog("==========开始抽奖任务==========================");
  // killApp(酷狗音乐);
  home();
  findAndClick("每日签到");
  findAndClick("立即签到|.*签到.*", 8000, 4000);
  sleep(15000);
  launchApp(酷狗音乐);
  sleep(1000)
  killApp(酷狗音乐);
  findAndClick("每日签到");
  launchApp(酷狗音乐);
  sleep(5000);
  if (!找字(/抽奖/, [100, 500, 980, 300])) {
    swipe(800, 700, 200, 700, 200);
    sleep(2000);
    showLog("滑动后重新查询立即抽奖入口");
    找字(/抽奖/, [100, 500, 980, 300]);
  }
  sleepT(5);
  if (!找字(/点击/, [device.width / 3, device.height / 2, 400, 600])) {
    return log("没有查询到点击按键，退出");
  }
  for (var i = 0; i < 15; i++) {
    sleepT(5);
    if (findAndClick("看视频.*")) {
      let 酷狗k = widgetGetOne("酷狗..k|1.");
      if (酷狗k) {
        sleepT(16);
        continue;
      } else {
        if (!widgetGetOne("抽奖活动")) {
          sleepT(10);
          back();
        }
      }
      if (找字(/点击/, [200, device.height - 400, device.width - 300, 300])) {
        sleep(2000);
        if (currentPackage() == "com.kugou.android") {
          back();
          sleepT(15);
          back();
        }
        launchApp(酷狗音乐);
      }
    }
  }

  showLog("=====================抽奖完成==========================");
  //返回上级做定时任务;
  back();
  sleep(1000);
  back();
  if (findAndClick("立即领取.*", 5000)) {
    浏览15秒();
  }
  showLog("任务完成");
  home();
}
//通用方法
/**
 * 根据内容获取一个对象
 *
 * @param {string} contentVal
 * @param {number} timeout 默认超时时间5秒
 * @param {boolean} containType 是否带回类型
 * @param {boolean} suspendWarning 是否隐藏warning信息
 * @param {function} appendFilter 附加查询条件 详见UiSelector
 */
function widgetGetOne(contentVal, timeout, containType, suspendWarning, appendFilter, options) {
  let target = null;
  let isDesc = false;
  let waitTime = timeout || 8000;
  let timeoutFlag = true;
  log(["try to find one: {} timeout: {}ms", contentVal.toString(), waitTime]);
  let checkResult = widgetCheck(contentVal, waitTime, true, appendFilter, options);
  if (!checkResult.timeout) {
    timeoutFlag = false;
    target = checkResult.target;
    isDesc = checkResult.isDesc;
  }
  // 当需要带回类型时返回对象 传递target以及是否是desc
  if (target && containType) {
    let result = {
      target: target,
      bounds: target.bounds(),
      isDesc: isDesc,
      content: isDesc ? target.desc() : target.text(),
    };
    return result;
  }
  return target;
}

/**
 * 替换控件搜索算法DFS,BFS,VDFS,VBFS,PDFS,PBFS,PVDFS,PVBFS
 * DFS,BFS为默认提供的深度优先和广度优先搜索算法
 * VDFS,VBFS为我修改的只搜索可见控件（控件包括父级不可见则直接跳过）深度优先和广度优先搜索算法 缺点是无法搜索不可见控件，适合一个界面中有巨量控件的时候用于加快搜索速度 实际数据抖音极速版从25s缩短到3s
 * PDFS,PBFS,PVDFS,PVBFS 是通过多线程搜索控件 大大加快搜索速度
 *
 * @param {string} algorithm 搜索算法DFS,BFS,VDFS,VBFS,PDFS,PBFS,PVDFS,PVBFS
 * @param {UiSelector} mselector
 * @return
 */
function wrapSelector(algorithm, appendFilter, mselector) {
  appendFilter =
    appendFilter ||
    function (matcher) {
      return matcher;
    };
  mselector = appendFilter(mselector || selector());
  if (!algorithm) {
    return mselector;
  }
  current = this.getCurrentAlgorithm();
  if (current == algorithm) {
    return mselector;
  }
  console.verbose("替换搜索算法为：" + algorithm + " 原始算法：" + current);
  return AlgorithmChanger.changeAlgorithm(mselector, algorithm);
}

/**
 * 校验控件是否存在
 * @param {String} contentVal 控件文本
 * @param {Number} timeoutSetting 超时时间 单位毫秒
 * @param {Boolean} containType 返回结果附带文本是desc还是text
 * @param {Object} options 额外参数
 * 超时返回false
 */
function widgetCheck(contentVal, timeoutSetting, containType, appendFilter, options) {
  options = options || {};
  let timeout = timeoutSetting || 5000;
  let timeoutFlag = true;
  let countDown = new java.util.concurrent.CountDownLatch(1);
  let matchRegex = new RegExp(contentVal);
  let isDesc = false;
  let target = null;
  let descThread = threads.start(function () {
    target = wrapSelector(options.algorithm, appendFilter).descMatches(matchRegex).findOne();
    let res = target.desc();
    log("find desc " + contentVal + " " + res);
    timeoutFlag = false;
    isDesc = true;
    countDown.countDown();
  });

  let textThread = threads.start(function () {
    target = wrapSelector(options.algorithm, appendFilter).textMatches(matchRegex).findOne();
    let res = target.text();
    showLog("find text " + contentVal + "  " + res);
    timeoutFlag = false;
    countDown.countDown();
  });

  let timeoutThread = threads.start(function () {
    sleep(timeout);
    countDown.countDown();
  });
  countDown.await();
  descThread.interrupt();
  textThread.interrupt();
  timeoutThread.interrupt();
  if (timeoutFlag) {
    showLog("cannot find any matches " + contentVal + " timeout:" + timeout);
  }
  if (containType) {
    // log("查询到目标:" + contentVal);
    return {
      timeout: timeoutFlag,
      target: target,
      bounds: target ? target.bounds() : null,
      isDesc: isDesc,
    };
  }
  return !timeoutFlag;
}

function clickCenter(obj) {
  click(obj.bounds().centerX(), obj.bounds().centerY());
}

/**
 * 找到并且点击 如果返回错误就点击中心 返回一个布尔值
 * @param {str} 要找的字符串 @param {sleepTime} 查询时间 @param {waitSleep} 等待waitSleep后查询
 */
function findAndClick(str, sleepTime, waitSleep) {
  waitSleep = waitSleep || 300;
  sleep(waitSleep);
  sleepTime = sleepTime || 8000;
  let widgetGet = widgetGetOne(str, sleepTime);
  if (widgetGet) {
    clickView(widgetGet);
    return widgetGet;
  }
  return false;
}

function clickView(obj) {
  try {
    clickCenter(obj);
    sleep(400);
    for (let i = 0; i < 4; i++) {
      if (obj && obj.click()) {
        console.log("Control clicked successfully" + obj.text());
        return true;
      } else {
        console.log("Control not clickable, checking parent");
        obj = obj && obj.parent();
      }
    }
    sleep(1000);
  } catch (error) {
    console.error("按键点击失败：" + error);
  }
}
// 杀死后台
function killApp(appName) {
  //填写包名或app名称都可以
  const name = getPackageName(appName); //通过app名称获取包名
  app.openAppSetting(name); //通过包名打开应用的详情页(设置页)
  sleep(2000); //稍微休息一下，不然看不到运行过程，自己用时可以删除这行
  findAndClick(/强.*|停.*|结.*/);
  findAndClick(/强.*|停.*|结.*/);
  findAndClick(/确定/);
  home();
  sleep(3000);
}
function showLog(msgLog) {
  let str = msgLog + " ";
  setFloatyInfo({ x: 100, y: 200 }, str, null);
}

function 打开酷狗任务中心() {
  showLog("启动酷狗音乐");
  if (!launchApp(酷狗音乐)) {
    log("打开失败退出");
    exit();
  }
  if (findAndClick("跳过|打开|允许")) {
    sleep(2000);
    back();
    findAndClick("关闭");
  }
  if (!findAndClick("我的", 8000, 1000)) {
    back();
    findAndClick("我的", 8000, 1000);
  }
  findAndClick("任务中心|金币中心", 8000, 1000);
}
function 浏览15秒() {
  sleep(3000);
  showLog("到浏览15秒任务方法");
  if (findAndClick("看视频.*|浏览.*秒.*金币")) {
    sleep(2000);
    if (findAndClick("允许|取消|确定")) {
      sleepT(13);
    } else {
      sleepT(6);
    }
    校验酷狗();
    sleepT(3);
    return true;
  } else {
    showLog("没有查询到浏览按键");
    if (widgetGetOne(".*提现|我的狗狗币")) {
      找字(/立即抽/, [100, 500, 980, 300]);
      sleepT(6);
      if (找字(/点击/, [400, 1290, 300, 300])) {
        sleepT(6);
      } else {
        back();
        return true;
      }
      return showLog("当前在抽奖页面");
    }
  }

  if (找字(/了解/, [200, 1900, 800, 300])) {
    sleepT(5);
    校验酷狗();
    sleep(2000);
    back();
    找字(/X/, [15, 144, 100, 234]);
  } else {
    showLog("视频广告等待15秒");
    sleepT(15);
    back();
    findAndClick(".*跳过.*");
  }
}

function FloatyUtil() {
  this.floatyWindow = null;
  this.floatyInitStatus = false;
  this.floatyLock = null;
  this.floatyCondition = null;
}
function FloatyUtilinit() {
  if (this.floatyInitStatus) {
    return true;
  }
  this.floatyLock = threads.lock();
  this.floatyCondition = this.floatyLock.newCondition();
  let _this = this;
  threads.start(function () {
    // 延迟初始化，避免死机
    sleep(400);
    _this.floatyLock.lock();
    try {
      if (_this.floatyInitStatus) {
        return true;
      }
      _this.floatyWindow = floaty.rawWindow(
        <frame gravity="left">
          <text id="content" textSize="16dp" textColor="#00ff00" bg="#000000" alpha="0.5" />
        </frame>
      );
      ui.run(function () {
        _this.floatyWindow.setTouchable(false);
        _this.floatyWindow.setPosition(150, 50);
        _this.floatyWindow.content.text("悬浮窗初始化成功");
      });
      _this.floatyInitStatus = true;
    } catch (e) {
      console.error("悬浮窗初始化失败" + e);
      _this.floatyWindow = null;
      _this.floatyInitStatus = false;
    } finally {
      _this.floatyCondition.signalAll();
      _this.floatyLock.unlock();
    }
  });
  this.floatyLock.lock();
  try {
    if (this.floatyInitStatus === false) {
      console.info("等待悬浮窗初始化");
      this.floatyCondition.await();
    }
  } finally {
    this.floatyLock.unlock();
  }
  console.info("悬浮窗初始化" + (this.floatyInitStatus ? "成功" : "失败"));
  return this.floatyInitStatus;
}

function setFloatyInfo(position, text, option) {
  option = option || {};
  if (this.floatyWindow === null) {
    FloatyUtilinit();
  }
  let _this = this;
  ui.run(function () {
    _this.floatyLock.lock();
    try {
      if (position && isFinite(position.x) && isFinite(position.y)) {
        _this.floatyWindow.setPosition(parseInt(position.x), parseInt(position.y) + 100);
      }
      if (text) {
        _this.floatyWindow.content.text(text);
        log(text);
      }
      if (option.textSize) {
        _this.floatyWindow.content.setTextSize(option.textSize);
      }
      if (typeof option.touchable !== "undefined") {
        _this.floatyWindow.setTouchable(option.touchable);
      }
    } finally {
      _this.floatyLock.unlock();
    }
  });
}

/**
 *
 * @param {正则表达/str/} str
 * @param {取值范围，起点+图片长宽} region
 * @param {} regex
 * @returns
 */
function 找字(str, region, regex, dianj) {
  if (运行环境haimbot) {
    let res = ocr.recognize(截图(str));
    for (let v of res.results) {
      log(v.bounds + "  " + v.text + " ");
      if (str.test(v.text)) {
        if (region != []) {
          if (
            region[0] < v.bounds.left &&
            region[1] < v.bounds.top &&
            region[2] > v.bounds.right - v.bounds.left &&
            region[3] > v.bounds.bottom - v.bounds.top
          ) {
            log("点击位置" + v.bounds.left + " " + v.bounds.top + " " + v.bounds.right + " " + v.bounds.bottom);
            if (!dianj) {
              if (v.bounds.right - v.bounds.left > device.width / 4 || v.bounds.bottom - v.bounds.top > device.height / 4) {
                click(Math.floor((v.bounds.right + v.bounds.left) / 2), Math.floor((v.bounds.top + v.bounds.bottom) / 2));
                return v;
              }

              click(v.bounds.left, v.bounds.top, v.bounds.right, v.bounds.bottom);
            }
            return v;
          } else {
            continue;
          }
        }
      }
    }
    return false;
  }

  region = region || [];
  let recognizeText = qq.recognizeWithBounds(截图(str), region, regex);
  log("文字查询结果：" + recognizeText.length);
  if (recognizeText.length == 0) {
    recognizeText = qq.recognizeWithBounds(截图(str), region, regex);
    log("第二次文字查询结果：" + recognizeText.length);
  }
  for (let v of recognizeText) {
    log(v.bounds + "  " + v.label);
    if (str.test(v.label)) {
      log("点击位置" + v.bounds.left + " " + v.bounds.top + " " + v.bounds.right + " " + v.bounds.bottom);
      if (!dianj) {
        if (v.bounds.right - v.bounds.left > device.width / 4 || v.bounds.bottom - v.bounds.top > device.height / 4) {
          click(Math.floor((v.bounds.right + v.bounds.left) / 2), Math.floor((v.bounds.top + v.bounds.bottom) / 2));
          return v;
        }
        click(v.bounds.left, v.bounds.top, v.bounds.right, v.bounds.bottom);
      }
      return v;
    }
  }
}

function 截图(str) {
  sleep(1000);
  log("截图找字：" + str);
  let 图片;
  try {
    图片 = images.captureScreen();
  } catch (error) {
    sleep(1000);
    log("图片截图错误，重新截图");
    threads.start(function () {
      findAndClick("允许|立即开始");
    });
    if (!requestScreenCapture()) {
      toast("请求截图失败");
      exit();
    }
    图片 = images.captureScreen();
  }
  threads.start(function () {
    sleep(5000);
    图片.recycle();
  });
  return 图片;
}

function 校验酷狗() {
  showLog("校验当前是不是在酷狗");
  if (currentPackage() != getPackageName(酷狗音乐)) {
    showLog("当前不在酷狗，打开酷狗app:" + currentPackage());
    home();
    findAndClick(酷狗音乐);
    // launchApp(酷狗音乐);
  } else {
    return;
  }
  sleep(2000);
  if (currentPackage() != getPackageName(酷狗音乐)) {
    showLog("打开酷狗失败重新尝试~");
    home();
    findAndClick(酷狗音乐);
    // launchApp(酷狗音乐);
  }
}
function sleepT(num, str) {
  str = str || "";
  num = num || 1;
  for (let index = num; index > 0; index--) {
    showLog("等待结束倒计时：" + index + "秒 " + str);
    sleep(1000);
  }
}
